package context

import (
	"container/list"
	"sync"
)

// Message represents a conversation message
type Message struct {
	Role    string
	Content string
	Tokens  int
}

// Conversation manages chat context and history
type Conversation struct {
	messages   *list.List
	maxTokens  int
	mutex      sync.RWMutex
	trimPolicy TrimPolicy
}

// TrimPolicy defines how to trim conversation history
type TrimPolicy interface {
	Trim(conv *Conversation) error
}

// NewConversation creates a new conversation manager
func NewConversation(maxTokens int, policy TrimPolicy) *Conversation {
	return &Conversation{
		messages:   list.New(),
		maxTokens:  maxTokens,
		trimPolicy: policy,
	}
}

// AddMessage adds a new message to the conversation
func (c *Conversation) AddMessage(msg Message) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	c.messages.PushBack(msg)

	// Apply trim policy if needed
	if c.trimPolicy != nil {
		return c.trimPolicy.Trim(c)
	}
	return nil
}

// GetMessages returns all messages in the conversation
func (c *Conversation) GetMessages() []Message {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	msgs := make([]Message, 0, c.messages.Len())
	for e := c.messages.Front(); e != nil; e = e.Next() {
		msgs = append(msgs, e.Value.(Message))
	}
	return msgs
}

// Clear clears all messages in the conversation
func (c *Conversation) Clear() {
	c.mutex.Lock()
	defer c.mutex.Unlock()
	c.messages.Init()
}
